import numpy as np
import csv
import random
from datetime import datetime
from time import strftime

'''
to calculate the false nagetive, false positive for the EBS

revision of test18
'''

def getCurTime():
    """
    get current time
    Return value of the date string format(%Y-%m-%d %H:%M:%S)
    """
    format='%Y-%m-%d %H:%M:%S'
    sdate = None
    cdate = datetime.now()
    try:
        sdate = cdate.strftime(format)
    except:
        raise ValueError
    return sdate

def build_unit_list(cancerFN):
    sKey = np.array([])
    #read contiguity file

    fn = unitCSV    # input csv location

    #print "Strat building csv lists..."

    ra = csv.DictReader(file(fn), dialect="excel")
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        temp = [int(float(record["ID"])), int(float(record[cancerFN])),int(float(record[popFN])),float(record["Area"]), 0, 0.0]
        #print temp
        sKey = np.append(sKey, temp)
    sKey.shape=(-1,6)
    return sKey

def build_region_list(inputCSV):
    fn = inputCSV
    ra = csv.DictReader(file(fn), dialect="excel")
    i = 0
    for record in ra:
        #print record[ra.fieldnames[0]], type(record[ra.fieldnames[-1]])
        unit_attri[i,4] = int(float(record[ra.fieldnames[-1]]))
        unit_attri[i,5] = float(record["SmoothedRate"])
        i = i + 1
        
def cal_region_attri(regionList):
    # calculate rate = cancer/pop for each region
    # return a list
    iLen = regionList.shape
    temp_reg_attri = np.array([])
    #temp_reg_cancer = np.array([])
    #temp_reg_pop = np.array([])

    i = 0
    while i < iLen[0]:
        temp = find_same_region(regionList[i])
        temp_cancer = 0
        temp_pop = 0
        temp_area = 0
        for item in temp:
            temp_cancer = temp_cancer + unit_attri[item, 1]
            temp_pop = temp_pop + unit_attri[item, 2]
            temp_area = temp_area + unit_attri[item, 3]
        temp_reg_attri = np.append(temp_reg_attri, [regionList[i], temp_cancer, temp_pop, temp_cancer/temp_pop, temp_area])
        i = i + 1

    temp_reg_attri.shape = (-1, 5)
    return temp_reg_attri
    #return temp_reg_rate, temp_reg_pop

def find_same_region(regionID):
    # return the original item id list within a region 
    iLen = unit_attri.shape
    i = 0
    temp = []
    while i < iLen[0]:
        if unit_attri[i,4] == regionID:
            temp = np.append(temp, unit_attri[i,0])
        i = i + 1
    return temp

def find_threshold_risk_area(unitList, listID):
    temp_cum_attri = np.array([])
    temp_unit_attri = np.array([])
    for unit in unitList:
        temp_unit_attri = np.append(temp_unit_attri, unit_attri[unit])
    temp_unit_attri.shape = (-1, 5)
    sort_temp_unit_attri = temp_unit_attri[np.argsort(-temp_unit_attri[:,4]),:]
    cumu_temp_unit_attri = sort_temp_unit_attri.cumsum(axis=0)
    # unit_attri = [FID, cancer, pop, area, smoothed_rate]
    # riskarea_attri = [total_cancer, total_pop, total_area]
    # returnID: 0-cancer, 1-pop, 2-area
    temp_sr_threshold = -1
    i = 0
    for item in cumu_temp_unit_attri:
        if 2 * item[returnID+1] > riskarea_attri[listID-1, returnID]:
            temp_sr_threshold = sort_temp_unit_attri[i, 4]
            break
        i = i + 1
    return temp_sr_threshold
    
def find_rep_region(unitList, listID):
    temp = np.array([])    
    for item in unitList:
        temp = np.append(temp, int(unit_attri[item,4]))

    dis_region = np.unique(temp) # distinct region ID in the unitList
    reg_riskarea_attri = np.array([])  #[[region_ID, cancer, pop, area]]
    temp_type_two_error = np.array([])

    '''
    unit_attri = [FID, cancer, pop, area, smoothed_rate]
    riskarea_attri = [total_cancer, total_pop, total_area]
    reg_attri = [region_ID, caner, pop, rate, area]
    * reg_riskarea_attri = [region_ID, cancer, pop, area]
    '''   
    
    for region in dis_region:
        reg_riskarea_attri = np.append(reg_riskarea_attri, [region, -1, -1, -1])
    reg_riskarea_attri.shape = (-1, 4)

    i = 0        
    for region in reg_riskarea_attri[:,0]:
        temp_pop = 0 
        temp_cancer = 0 
        temp_area = 0
        for unit in unitList:
            if int(unit_attri[unit, 4]) == int(region):
                temp_pop = temp_pop + unit_attri[unit, 2]
                temp_cancer = temp_cancer +  unit_attri[unit, 1]
                temp_area = temp_area + unit_attri[unit, 3]        
        reg_riskarea_attri[i, 1] = temp_cancer
        reg_riskarea_attri[i, 2] = temp_pop
        reg_riskarea_attri[i, 3] = temp_area
        i = i + 1
    temp_rep_id = np.array([])

    '''
    unit_attri = [FID, cancer, pop, area, regionID]
    riskarea_attri = [total_cancer, total_pop, total_area]
    reg_attri = [region_ID, caner, pop, rate, area]
    * reg_riskarea_attri = [region_ID, cancer, pop, area]
    '''
    falseNegative = 0
    falsePositive = 0
    detectedTruth = 0

    temp_total_pop = 0    

    iLen = dis_region.shape    

    if returnID == 1: # pop
        i = 0
        while i < iLen[0]:
            if reg_riskarea_attri[i,2]/riskarea_attri[listID-1, 1] > 0.5 or reg_riskarea_attri[i,2]/reg_attri[reg_riskarea_attri[i,0],2] > 0.5:  
                temp_rep_id = np.append(temp_rep_id, i)
                detectedTruth = detectedTruth + reg_riskarea_attri[i,2]
                temp_total_pop = temp_total_pop + reg_attri[reg_riskarea_attri[i,0],2]
            i = i + 1
        falsePositive = riskarea_attri[listID-1, 1] - detectedTruth
        falseNegative = temp_total_pop - detectedTruth
    elif returnID == 0: # cancer
        i = 0
        while i < iLen[0]:
            if reg_riskarea_attri[i,1]/riskarea_attri[listID-1,0] > 0.5 or reg_riskarea_attri[i,1]/reg_attri[reg_riskarea_attri[i,0],1] > 0.5: 
                temp_rep_id = np.append(temp_rep_id, i)
                detectedTruth = detectedTruth + reg_riskarea_attri[i,1]
                temp_total_pop = temp_total_pop + reg_attri[reg_riskarea_attri[i,0],1]
            i = i + 1
        falsePositive = riskarea_attri[listID-1, 0] - detectedTruth
        falseNegative = temp_total_pop - detectedTruth
    elif returnID == 2: # area
        i = 0
        while i < iLen[0]:
            if reg_riskarea_attri[i,3]/riskarea_attri[listID-1,2] > 0.5 or reg_riskarea_attri[i,1]/reg_attri[reg_riskarea_attri[i,0],1] > 0.5:  
                temp_rep_id = np.append(temp_rep_id, i)
                detectedTruth = detectedTruth + reg_riskarea_attri[i,3]
                temp_total_pop = temp_total_pop + reg_attri[reg_riskarea_attri[i,0],4]
            i = i + 1
        falsePositive = riskarea_attri[listID-1, 2] - detectedTruth
        falseNegative = temp_total_pop - detectedTruth
    temp_rep_id = np.unique(temp_rep_id)
    

    if temp_rep_id.shape[0] == 0:
        temp_type_two_error = np.append(temp_type_two_error, [repeat, listID, returnID])
        
    temp_reg_id = []
    for item in temp_rep_id:
        temp_reg_id.append(int(dis_region[item]))

    temp_DFF = np.array([detectedTruth, falsePositive, falseNegative])        
    return temp_reg_id
    
def find_max_id(list):
    # return the id of the maximum value
    i = 0
    temp_max = 0
    temp_max_id = 0
    
    for item in list:
        if item > temp_max:
            temp_max = item
            temp_max_id = i
        i = i + 1
    return temp_max_id           

def find_min_id(list):
    # return the id of the maximum value
    i = 0
    temp_min = 1000000
    temp_min_id = 0
    
    for item in list:
        if item < temp_min:
            temp_min = item
            temp_min_id = i
        i = i + 1
    return temp_min_id

def calMeasure():
    high_risk_region = np.array([])
    low_risk_regioin = np.array([])

    tempListID = 1 
    tempID = find_rep_region(H1, tempListID)
    high_risk_region = np.append(high_risk_region, tempID)
    
    tempListID = 2
    tempID = find_rep_region(L2, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    
    tempListID = 3
    tempID = find_rep_region(H3, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)

    tempListID = 4
    tempID = find_rep_region(H4, tempListID)   
    high_risk_region = np.append(high_risk_region, tempID)

    tempListID = 5
    tempID = find_rep_region(L5, tempListID)
    low_risk_regioin = np.append(low_risk_regioin, tempID)

    tempListID = 6    
    tempID = find_rep_region(L6, tempListID)    
    low_risk_regioin = np.append(low_risk_regioin, tempID)
    
    tempListID = 7    
    tempID = find_rep_region(H7, tempListID)    
    high_risk_region = np.append(high_risk_region, tempID)
        
    temp_high_rate = np.array([])
    for region in high_risk_region:
        temp_high_rate = np.append(temp_high_rate, [region, reg_attri[int(region), 3]])
    temp_high_rate.shape = (-1,2)

    temp_low_rate = np.array([])    
    for region in low_risk_regioin:
        temp_low_rate = np.append(temp_low_rate, [region, reg_attri[int(region), 3]])        
    temp_low_rate.shape = (-1,2)
    
    temp_total_high = 0
    temp_total_low = 0

    #print temp_low_rate[:,1]
    #max_low_rate = temp_low_rate[:,1].max()
    #min_high_rate = temp_high_rate[:,1].min()
    
    high_measure = np.array([0.0,0,0,0,0]) # [turePositive, falsePositive, falseNegative, count_within_risk_area, count_without]
    low_measure = np.array([0.0,0,0,0,0])  # [turePositive, falsePositive, falseNegative, count_within_risk_area, count_without]    

    for item in unit_attri:    
        if temp_high_rate.shape[0] <> 0:
            min_high_rate = temp_high_rate[:,1].min()
            if temp_low_rate.shape[0] <> 0:
                max_low_rate = temp_low_rate[:,1].max()
                if item[5] > min_high_rate:
                    if int(item[0]) in high_risk_area_id:
                        high_measure[0] = high_measure[0] + item[returnID+1]
                        high_measure[3] = high_measure[3] + 1
                    else:
                        high_measure[1] = high_measure[1] + item[returnID+1]
                        high_measure[4] = high_measure[4] + 1
                elif item[5] < max_low_rate:
                    if int(item[0]) in low_risk_area_id:
                        low_measure[0] = low_measure[0] + item[returnID+1]
                        low_measure[3] = low_measure[3] + 1
                    else:
                        low_measure[1] = low_measure[1] + item[returnID+1]
                        low_measure[4] = low_measure[4] + 1
            else:
                if item[5] > min_high_rate:
                    if int(item[0]) in high_risk_area_id:
                        high_measure[0] = high_measure[0] + item[returnID+1]
                        high_measure[3] = high_measure[3] + 1
                    else:
                        high_measure[1] = high_measure[1] + item[returnID+1]
                        high_measure[4] = high_measure[4] + 1 
        else:
            if temp_low_rate.shape[0] <> 0:
                max_low_rate = temp_low_rate[:,1].max()
                if item[5] < max_low_rate:
                    if int(item[0]) in low_risk_area_id:
                        low_measure[0] = low_measure[0] + item[returnID+1]
                        low_measure[3] = low_measure[3] + 1
                    else:
                        low_measure[1] = low_measure[1] + item[returnID+1]
                        low_measure[4] = low_measure[4] + 1
                        
    high_measure[2] = high_riskarea_attri[returnID] - high_measure[0]
    low_measure[2] = low_riskarea_attri[returnID] - low_measure[0]
    
    high_measure = np.append(high_measure, low_measure)

    return high_measure
    
def cal_riskare_attri():
    temp_popcancer = np.array([])
    temp_high_popcancer = np.array([0,0,0.0]) #[cancer, pop, area]
    temp_low_popcancer = np.array([0,0,0.0]) #[cancer, pop, area]
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(H1)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_high_popcancer[0] = temp_high_popcancer[0] + temp_cancer
    temp_high_popcancer[1] = temp_high_popcancer[1] + temp_pop
    temp_high_popcancer[2] = temp_high_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(L2)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_low_popcancer[0] = temp_low_popcancer[0] + temp_cancer
    temp_low_popcancer[1] = temp_low_popcancer[1] + temp_pop
    temp_low_popcancer[2] = temp_low_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(H3)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_high_popcancer[0] = temp_high_popcancer[0] + temp_cancer
    temp_high_popcancer[1] = temp_high_popcancer[1] + temp_pop
    temp_high_popcancer[2] = temp_high_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(H4)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_high_popcancer[0] = temp_high_popcancer[0] + temp_cancer
    temp_high_popcancer[1] = temp_high_popcancer[1] + temp_pop
    temp_high_popcancer[2] = temp_high_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(L5)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_low_popcancer[0] = temp_low_popcancer[0] + temp_cancer
    temp_low_popcancer[1] = temp_low_popcancer[1] + temp_pop
    temp_low_popcancer[2] = temp_low_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(L6)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_low_popcancer[0] = temp_low_popcancer[0] + temp_cancer
    temp_low_popcancer[1] = temp_low_popcancer[1] + temp_pop
    temp_low_popcancer[2] = temp_low_popcancer[2] + temp_area
    
    temp_cancer, temp_pop, temp_area = cal_list_pop(H7)
    temp_popcancer = np.append(temp_popcancer, [temp_cancer, temp_pop, temp_area])
    temp_high_popcancer[0] = temp_high_popcancer[0] + temp_cancer
    temp_high_popcancer[1] = temp_high_popcancer[1] + temp_pop
    temp_high_popcancer[2] = temp_high_popcancer[2] + temp_area
    
    temp_popcancer.shape = (-1, 3)
    return temp_popcancer, temp_high_popcancer, temp_low_popcancer

def cal_list_pop(list):
    # calculate the total pop and cancer in the input list
    temp_pop = 0
    temp_cancer = 0
    temp_area = 0
    for item in list:
        temp_pop = temp_pop + unit_attri[item, 2]
        temp_cancer = temp_cancer + unit_attri[item, 1]
        temp_area = temp_area + unit_attri[item, 3]
    return temp_cancer, temp_pop, temp_area 

#--------------------------------------------------------------------------
#MAIN

if __name__ == "__main__":
    #inputs = get_inputs()
    print "begin at " + getCurTime()

    H1 = [8,16,844,915,919,921,923,924]
    L2 = [5,103,106,513,517,518,520,531,534,535,536,541]
    H3 = [63,265,267,268,333,336,337,339,340,342,343,348]
    H4 = [13,174,178,198,886,887,888,889,890]
    L5 = [146,171,182,810,811,814,815,864,867]
    L6 = [20,133,692,694,695,696,698,702,705]
    H7 = [69,70,87,88,369,370,372,442,443]
    high_risk_area_id = H1 + H3 + H4 + H7
    low_risk_area_id = L2 + L5 + L6
    unitCSV = "C:/TP1000_1m.csv"
    popFN = "pop"

    j = 0
    while j < 3:
        if j == 0:
            soMethod = "OO"
        elif j == 1:
            soMethod = "SO"
        elif j == 2:
            soMethod = "SS"
        else:
            print "error in j value!"
            break

        filePath = "C:/_DATA/CancerData/test/Jan15/Thousand/8000/"+ soMethod +"_WARD/"

        returnID = 0  # 0: return max_cancer, 1: return max_pop, 2: return max_area
    
        while returnID < 3:
            type_two_error = np.array([])
            high_low_measure = np.array([])
            new_measure = np.array([])
            repeat = 1

            
            #while repeat < 1001:
            while repeat < 1001:
                regionCSV = filePath + soMethod +"_WARDcancer"+ str(repeat) +".csv"
                sField_Ob = "cancer" + str(repeat)
                unit_attri = build_unit_list(sField_Ob) # [FID, cancer, pop, area, regionID, smoothed_rate]
                build_region_list(regionCSV)
                dis_reg = np.unique(unit_attri[:,4])
                riskarea_attri, high_riskarea_attri, low_riskarea_attri = cal_riskare_attri()  # [total_cancer, total_pop, total_area]
                reg_attri = cal_region_attri(dis_reg) # [region_ID, caner, pop, rate, area]

                '''
                unit_attri = [FID, cancer, pop, area, regionID]
                riskarea_attri = [total_cancer, total_pop, total_area]
                reg_attri = [region_ID, caner, pop, rate, area]
                '''            
                temp_mearsure = calMeasure()
                new_measure = np.append(new_measure, temp_mearsure)
                repeat = repeat + 1

            new_measure.shape = (-1,10)


            if returnID == 1:
                txtNameNM = filePath + soMethod + "_POP_EBSMeasure.csv"
            elif returnID == 0:
                txtNameNM = filePath + soMethod + "_Cancer_EBSMeasure.csv"
            elif returnID == 2:
                txtNameNM = filePath + soMethod + "_Area_EBSMeasure.csv"
            
            np.savetxt(txtNameNM, new_measure, delimiter=',')
            #print new_measure
            del type_two_error, high_low_measure, repeat, new_measure
            returnID = returnID + 1
        j = j + 1
    print "end at " + getCurTime()
    print "========================================================================"  


           
